// 1. 修改 TokenServiceImpl.java 实现类
package com.doubao.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.doubao.common.result.Result;
import com.doubao.user.entity.TokenConsumptionRecord;
import com.doubao.user.entity.User;
import com.doubao.user.mapper.TokenConsumptionRecordMapper;
import com.doubao.user.mapper.UserMapper;
import com.doubao.user.service.TokenService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Token管理服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class TokenServiceImpl implements TokenService {

    private final UserMapper userMapper;
    private final TokenConsumptionRecordMapper consumptionRecordMapper;
    // 每条消息基本消耗的token数量
    private static final int MESSAGE_TOKEN_COST = 10;
    // 新用户初始token数量
    private static final int INITIAL_TOKEN_AMOUNT = 10000;

    @Override
    public boolean hasEnoughTokens(Long userId, int requiredTokens) {
        if (userId == null) {
            return false;
        }

        User user = userMapper.selectById(userId);
        if (user == null) {
            return false;
        }

        return user.getTotalTokensBalance() >= requiredTokens;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> consumeTokens(Long userId, int promptTokens, int completionTokens,
                                      Long sessionId, Long messageId, Long providerId, String modelId) {
        if (userId == null) {
            return Result.failed("用户ID不能为空");
        }

        // 获取用户信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            return Result.failed("用户不存在");
        }

        int totalTokensToConsume = promptTokens + completionTokens;
        int currentBalance = user.getTotalTokensBalance();

        // 检查余额是否足够
        if (currentBalance < totalTokensToConsume) {
            return Result.failed("Token余额不足，请充值");
        }

        // 更新用户token余额
        int newBalance = currentBalance - totalTokensToConsume;
        user.setTotalTokensBalance(newBalance);
        user.setTotalTokensUsed(user.getTotalTokensUsed() + totalTokensToConsume);
        userMapper.updateById(user);

        // 记录消费记录
        TokenConsumptionRecord record = new TokenConsumptionRecord();
        record.setUserId(userId);
        record.setConsumptionDate(LocalDate.now());
        record.setSessionId(sessionId);
        record.setMessageId(messageId);
        record.setPromptTokens(promptTokens);
        record.setCompletionTokens(completionTokens);
        record.setTotalTokens(totalTokensToConsume);
        record.setBalanceAfter(newBalance);
        record.setAiProviderId(providerId);
        record.setAiModelId(modelId);
        consumptionRecordMapper.insert(record);

        log.info("用户[{}]消费Tokens: prompt={}, completion={}, 总计={}, 剩余={}",
                userId, promptTokens, completionTokens, totalTokensToConsume, newBalance);

        return Result.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> preDeductTokens(Long userId, int baseTokens) {
        if (userId == null) {
            return Result.failed("用户ID不能为空");
        }

        // 获取用户信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            return Result.failed("用户不存在");
        }

        // 使用消息基本token消耗
        int tokensToDeduct = baseTokens > 0 ? baseTokens : MESSAGE_TOKEN_COST;
        int currentBalance = user.getTotalTokensBalance();

        // 检查余额是否足够
        if (currentBalance < tokensToDeduct) {
            return Result.failed("Token余额不足，请充值");
        }

        try {
            // 直接使用SQL更新语句，类似于你刚才测试的SQL
            String sql = "UPDATE user SET " +
                    "total_tokens_balance = total_tokens_balance - " + tokensToDeduct + ", " +
                    "total_tokens_used = total_tokens_used + " + tokensToDeduct + ", " +
                    "updated_at = NOW() " +
                    "WHERE id = " + userId;

            // 使用JDBC模板或MyBatis执行SQL
            //int rows = userMapper.executeUpdateSql(sql);
            int rows = userMapper.updateTokensBalanceAndUsed(userId, tokensToDeduct);
            if (rows <= 0) {
                log.error("更新用户token数据失败: userId={}, deduct={}", userId, tokensToDeduct);
                return Result.failed("更新token数据失败");
            }

            // 更新完成后查询一次用户数据，确认更新结果
            User updatedUser = userMapper.selectById(userId);
            log.info("用户[{}]预扣减Tokens: {}, 剩余={}, 已使用={}",
                    userId, tokensToDeduct, updatedUser.getTotalTokensBalance(),
                    updatedUser.getTotalTokensUsed());

            return Result.success();
        } catch (Exception e) {
            log.error("预扣减Token时发生异常: {}", e.getMessage(), e);
            return Result.failed("预扣减失败: " + e.getMessage());
        }
    }

    @Override
    public int getUserTokenBalance(Long userId) {
        if (userId == null) {
            return 0;
        }

        User user = userMapper.selectById(userId);
        if (user == null) {
            return 0;
        }

        return user.getTotalTokensBalance();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> rechargeTokens(Long userId, int tokenAmount) {
        if (userId == null) {
            return Result.failed("用户ID不能为空");
        }

        if (tokenAmount <= 0) {
            return Result.failed("充值金额必须大于0");
        }

        // 获取用户信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            return Result.failed("用户不存在");
        }

        // 更新用户token余额
        int newBalance = user.getTotalTokensBalance() + tokenAmount;
        user.setTotalTokensBalance(newBalance);
        userMapper.updateById(user);

        log.info("用户[{}]充值Tokens: {}, 当前余额={}", userId, tokenAmount, newBalance);

        return Result.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> initializeUserTokens(Long userId) {
        if (userId == null) {
            return Result.failed("用户ID不能为空");
        }

        User user = userMapper.selectById(userId);
        if (user == null) {
            return Result.failed("用户不存在");
        }

        // 设置初始token余额为100
        user.setTotalTokensBalance(100);
        userMapper.updateById(user);

        log.info("初始化用户[{}]的token余额: 100", userId);

        return Result.success();
    }

    @Override
    public boolean hasEnoughTokensForMessage(Long userId) {
        return hasEnoughTokens(userId, MESSAGE_TOKEN_COST);
    }

    @Override
    public Result<Object> getConsumptionHistory(Long userId, int page, int size) {
        if (userId == null) {
            return Result.failed("用户ID不能为空");
        }

        // 分页查询消费记录
        Page<TokenConsumptionRecord> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<TokenConsumptionRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TokenConsumptionRecord::getUserId, userId)
                .orderByDesc(TokenConsumptionRecord::getCreatedAt);

        Page<TokenConsumptionRecord> result = consumptionRecordMapper.selectPage(pageParam, wrapper);

        // 处理返回结果
        List<Map<String, Object>> records = result.getRecords().stream().map(record -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id", record.getId());
            map.put("date", record.getConsumptionDate().toString());
            map.put("promptTokens", record.getPromptTokens());
            map.put("completionTokens", record.getCompletionTokens());
            map.put("totalTokens", record.getTotalTokens());
            map.put("balanceAfter", record.getBalanceAfter());
            map.put("createdAt", record.getCreatedAt());
            return map;
        }).collect(Collectors.toList());

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("records", records);
        resultMap.put("total", result.getTotal());
        resultMap.put("pages", result.getPages());
        resultMap.put("current", result.getCurrent());
        resultMap.put("size", result.getSize());

        return Result.success(resultMap);
    }

    @Override
    public Result<Object> getConsumptionStats(Long userId, String startDate, String endDate) {
        if (userId == null) {
            return Result.failed("用户ID不能为空");
        }

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate start, end;
        try {
            start = LocalDate.parse(startDate, formatter);
            end = LocalDate.parse(endDate, formatter);
        } catch (Exception e) {
            return Result.failed("日期格式错误，请使用yyyy-MM-dd格式");
        }

        // 查询指定日期范围内的消费统计
        List<Map<String, Object>> stats = consumptionRecordMapper.selectConsumptionStatsByDateRange(
                userId, start, end);

        // 获取总消费量
        Integer totalConsumption = consumptionRecordMapper.selectTotalConsumptionByDateRange(
                userId, start, end);

        // 获取当前余额
        User user = userMapper.selectById(userId);
        Integer currentBalance = user != null ? user.getTotalTokensBalance() : 0;

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("dailyStats", stats);
        resultMap.put("totalConsumption", totalConsumption);
        resultMap.put("currentBalance", currentBalance);
        resultMap.put("startDate", startDate);
        resultMap.put("endDate", endDate);

        return Result.success(resultMap);
    }
}
